package szad.org.player;

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;

import com.google.gson.Gson;

import szad.org.dao.GsonRequest;
import szad.org.dao.GsonRequest.Movement;
import szad.org.dao.GsonResponse;
import szad.org.model.Dao;
import szad.org.model.Mezo;
import szad.org.model.Munka;

public class Player {
	private Dao dao;
	private Gson gson = new Gson();
	private int hqx, hqy;
	private int[][] hqdist;

	private class Coord {
		public int x;
		public int y;
		public int length;

		public Coord(int x, int y, int length) {
			this.x = x;
			this.y = y;
			this.length = length;
		}
	}

	public void initMap(GsonResponse gsresp) {
		dao = new Dao(gsresp.mapSize);
		Iterator<Entry<Integer, Integer[]>> it = gsresp.roadBlocks.entrySet()
				.iterator();
		while (it.hasNext()) {
			Map.Entry<Integer, Integer[]> pairs = (Map.Entry<Integer, Integer[]>) it
					.next();
			System.out.println(pairs.getKey() + " = " + pairs.getValue());
			it.remove(); // avoids a ConcurrentModificationException
			for (int i = 0; i < pairs.getValue().length; i++) {
				Integer[] arr = pairs.getValue();
				dao.setSzomszedFalse(pairs.getKey(), arr[i]);
			}
		}

		GsonResponse.Agent[] agents = gsresp.agents;
		for (int i = 0; i < agents.length; i++) {
			dao.ujSzakember(agents[i].coordinate, agents[i].type,
					agents[i].agentId, agents[i].owner);
		}

		GsonResponse.Task[] tasks = gsresp.tasks;
		for (int i = 0; i < tasks.length; i++) {
			dao.setMunka(tasks[i].coordinate, tasks[i].type, tasks[i].duration,
					tasks[i].remaining, tasks[i].profit, tasks[i].penalty,
					tasks[i].status);
		}

		GsonResponse.HeadQuarter[] headquarter = gsresp.headQuarters;
		for (int i = 0; i < headquarter.length; i++) {
			dao.setSzekhely(headquarter[i].coordinate, headquarter[i].owner);
			if (headquarter[i].owner.equals("me")) {
				int n = dao.getN();
				hqdist = new int[dao.getN()][dao.getN()];

				for (int i1 = 0; i1 < dao.getN(); i1++) {
					for (int j1 = 0; j1 < dao.getN(); j1++) {
						hqdist[i1][j1] = Integer.MAX_VALUE;
					}
				}
				hqx = dao.getX(headquarter[i].coordinate);
				hqy = dao.getY(headquarter[i].coordinate);
				LinkedList<Coord> coords = new LinkedList<>();

				coords.add(new Coord(hqx, hqy, 0));
				hqdist[hqx][hqy] = 0;
				// System.out.println(hqx + " " + hqy + " " + dao.getN());
				while (!coords.isEmpty()) {
					Coord c = coords.getFirst();
					coords.removeFirst();
					System.out.println(c.x + " " + c.y + " " + c.length);

					for (int d = 0; d < 4; d++) {
						int x = c.x + Mezo.szomszed_coordx[d][0];
						int y = c.y + Mezo.szomszed_coordx[d][1];
						if (x >= 0
								&& x < n
								&& y >= 0
								&& y < n
								&& dao.getSzomszed(dao.coordToIndex(c.x, c.y),
										dao.coordToIndex(x, y))
								&& c.length + 1 < hqdist[x][y]) {
							coords.addLast(new Coord(x, y, c.length + 1));
							hqdist[x][y] = c.length + 1;
						}
					}
				}
			}
		}
		/*
		 * for(int i=0; i<dao.getN(); i++) { for(int j=0; j<dao.getN(); j++) {
		 * System.out.print(hqdist[i][j] + " "); } System.out.println(); }
		 */
	}

	public Dao getDao() {
		return dao;
	}

	LinkedList<GsonRequest.Movement> order;
	boolean first = true;
	
	public String nextTurn(int turn) {
		order = new LinkedList<>();
		GsonRequest request = new GsonRequest(turn);
		if(first) {
			request.hire = new int[]{0,0,3};
			first = false;
		} else {
			int i,j;
			int n = dao.getN();
		
			for (i = 0; i < n; i++) {
				for (j = 0; j < n; j++) {
					if(dao.mezok[i][j].szakember.isFree) {
						dao.mezok[i][j].szakember.isFree = true;
					}
				}
			}

		
		
		for (i = 0; i < n; i++) {
			for (j = 0; j < n; j++) {
				Mezo mezo = dao.getMezo(i, j);
				Munka munka = dao.getMunka(i, j);
				if (munka != null && munka.getStatus().equals("free") && !munka.ordered) {
					// hqdist[i][j];
					int visited[][] = new int[n][n];

					for (int i1 = 0; i1 < n; i1++) {
						for (int j1 = 0; j1 < n; j1++) {
							visited[i1][j1] = Integer.MAX_VALUE;
						}
					}
					LinkedList<Coord> coords = new LinkedList<>();

					coords.add(new Coord(i, j, 0));
					visited[i][j] = 0;
					boolean done = false;
					// System.out.println(hqx + " " + hqy + " " + dao.getN());
					while (!coords.isEmpty() && !done) {
						Coord c = coords.getFirst();
						coords.removeFirst();
						//System.out.println(c.x + " " + c.y + " " + c.length);

						for (int d = 0; d < 4 && !done; d++) {
							int x = c.x + Mezo.szomszed_coordx[d][0];
							int y = c.y + Mezo.szomszed_coordx[d][1];
							if(dao.mezok[x][y].szakember.isFree && dao.mezok[x][y].szakember.owner.equals("me")) {
								dao.mezok[x][y].szakember.isFree = false;
								dao.mezok[x][y].munka.ordered = true;
								GsonRequest.Movement movement = request.new Movement();
								movement.coordinate = dao.coordToIndex(c.x, c.y);
								movement.agentid = dao.mezok[x][y].szakember.owner;
								order.add(movement);
								done = true;
							}
							if (x >= 0 && x < n && y >= 0 && y < n && dao.getSzomszed(dao.coordToIndex(c.x, c.y),dao.coordToIndex(x, y)) && c.length + 1 < visited[x][y]) {
								coords.addLast(new Coord(x, y, c.length + 1));
								visited[x][y] = c.length + 1;
							}
						}
					}

					/*
					  int length = 0; int visited[][] = new int[n][n];
					  Arrays.fill(visited, -1);
					  
					  visited[i][j] = 0; for(int d=0; d<4; d++) {
					  
					  if(mezo.getSzomszed(d)) { int x =
					  i+Mezo.szomszed_coordx[d][0]; int y =
					  j+Mezo.szomszed_coordx[d][1]; Mezo szomszed =
					  dao.getMezo(x, y); if(visited[x][y] == -1) {
					  visited[x][y] = length; Munka ujmunka = dao.getMezo(x,
					  y).munka; if(ujmunka.getStatus().equals("free")) {
					  
					  } } } }
					 */
				}
			}
		}
		}

		// request.hire

		// dao.szakemberMozgat(honnan, hova)
		
		Movement[] array = new Movement[order.size()];
		for (int i = 0; i < order.size(); i++) {
		    array[i] = order.get(i); // Watch out for NullPointerExceptions!
		}
		request.move = array;
		
		return gson.toJson(request, GsonRequest.class);
	}

}
